﻿' ------------------------------------------------------------------------------
' This form shows the progress of the image cataloging process for each image.
' As images are located and their time zones are determined, a map is updated
' to show these spatial features, giving the user a sense of the spatial
' capabilities of the database and the use of the datetimeoffset SQL type.
' ------------------------------------------------------------------------------
' This file is part of the SQL Server 2008 Technology Demonstration. This
' application was designed and coded by Eric Weitzman, LandTime Inc, for
' Microsoft Corporation. Contact Ed Katibah at Microsoft about this demo.
' Copyright © 2008 Microsoft Corporation. All rights reserved.
' ------------------------------------------------------------------------------

Imports SpatialAlbum.WinForms.DundasMapVeneer.EnumExtent
Imports Dundas.Maps.WinControl
Imports System.Windows.Media.Imaging

Public Class ImageLoaderForm
    Inherits System.Windows.Forms.Form

    Private WithEvents m_job As ImageJob
    Private m_map As DundasMapVeneer = Nothing

    Const STEP_COUNT As Integer = 7 ' number of steps (or events) per image

    ' BUG: if BeginInvoke() is used when needed, events aren't either delivered or processed
    ' in the correct order and the slider bars and text box don't always update as they
    ' should. Not using BeginInvoke() produces the correct behavior, and fortunately no
    ' reentrance problems.

    Const USE_INVOKE As Boolean = True

    Private Sub ImageLoaderForm_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        barJob.Maximum = STEP_COUNT
        barJob.Step = 1
        barOverall.Step = 1
        barJob.Value = 0
        barOverall.Value = 0
        txtStatus.Text = "You can drag and drop jpeg files onto this window to load them into the database."
        txtStatus.Select(0, 0)

        AddHandler g_imageloader.StartLoadingImage, AddressOf StartLoadingImage
        AddHandler g_imageloader.ImageLoaded, AddressOf ImageLoaded
        AddHandler Me.DragDrop, AddressOf DragDropHelper.OnDragDrop
        AddHandler Me.DragEnter, AddressOf DragDropHelper.OnDragEnter

        If m_map Is Nothing Then
            m_map = New DundasMapVeneer(MapControl1)
            m_map.LoadMap(False)
            m_map.LoadTimeZones(False, False)
        End If

        chkTimeZones.Checked = False
        rdoWorld.Checked = True

        g_sqlinspector.Show()
        MoveSqlForm()

    End Sub

    Private Sub ImageLoaderForm_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        RemoveHandler g_imageloader.StartLoadingImage, AddressOf StartLoadingImage
        RemoveHandler g_imageloader.ImageLoaded, AddressOf ImageLoaded
        g_loaderform = New ImageLoaderForm
        g_sqlinspector.Hide()
    End Sub

    Private Sub MoveSqlForm()
        g_sqlinspector.SetDesktopBounds(DesktopLocation.X, DesktopLocation.Y + Height, Me.Width, g_sqlinspector.Height)
    End Sub

    Private Delegate Sub DlgJobEvent(ByVal job As ImageJob)
    Private Sub StartLoadingImage(ByVal job As ImageJob)
        If USE_INVOKE And InvokeRequired Then
            BeginInvoke(New DlgJobEvent(AddressOf StartLoadingImage), job)
        Else
            m_job = job
            barJob.Value = 0
            Dim done As Integer = g_imageloader.DoneCount
            Dim queued As Integer = g_imageloader.QueueCount
            txtStatus.Text = (done + 1) & "/" & (queued + done + 1) & " - image '" & m_job.Name & "' "
            barOverall.Value = done
            barOverall.Maximum = queued + done + 1
            Me.Update()
            My.Application.DoEvents()
        End If
    End Sub

    Private Sub ImageLoaded(ByVal job As ImageJob)
        If USE_INVOKE And InvokeRequired Then
            BeginInvoke(New DlgJobEvent(AddressOf ImageLoaded), job)
        Else
            barOverall.PerformStep()
            If barOverall.Value = barOverall.Maximum Then
                txtStatus.Text = txtStatus.Text & vbCrLf & "loaded " & barOverall.Maximum & " image(s)"
                m_map.ClearHighlights()
            End If
            m_job = Nothing
            Me.Update()
            My.Application.DoEvents()
        End If
    End Sub

    Private Sub m_job_Started() Handles m_job.Started
        UpdateProgress("", True)
    End Sub

    Private Sub m_job_InsertedRow(ByVal thumb As BitmapImage) Handles m_job.InsertedRow
        If thumb Is Nothing Then
            UpdateProgress("- inserted row (no thumbnail)", True)
        Else
            UpdateProgress("- inserted row", True)
        End If
    End Sub

    Private Sub m_job_Filestream() Handles m_job.Filestream
        UpdateProgress("- filestream", True)
    End Sub

    Private Delegate Sub DlgOnLocation(ByVal point As LatLong)
    Private Sub m_job_Location(ByVal point As LatLong) Handles m_job.Location
        If USE_INVOKE And InvokeRequired Then
            BeginInvoke(New DlgOnLocation(AddressOf m_job_Location), point)
        Else
            If point.IsNull Then
                UpdateProgress("- location (not found)", False)
            Else
                UpdateProgress("- location", False)
            End If
            If point.IsNull Then Return
            m_map.AddPhoto(point, True)
            Me.Update()
            My.Application.DoEvents()
        End If
    End Sub

    Private Sub m_job_Metadata() Handles m_job.Metadata
        UpdateProgress("- metadata", True)
    End Sub

    Private Delegate Sub DlgTimeZone(ByVal tz As SpatialAlbum.Core.TimeZone)
    Private Sub m_job_TimeZone(ByVal tz As SpatialAlbum.Core.TimeZone) Handles m_job.TimeZoneFound
        If USE_INVOKE And InvokeRequired Then
            BeginInvoke(New DlgTimeZone(AddressOf m_job_TimeZone), tz)
        Else
            If tz Is Nothing Then
                UpdateProgress("- time zone (not found)")
                barJob.PerformStep() ' because the next event for the datetimeoffset won't be fired
            Else
                UpdateProgress("- time zone")
            End If
            If tz IsNot Nothing Then
                Dim elements As ArrayList = MapControl1.Find(tz.UniqueID.ToString, False, True)
                For Each e As Object In elements
                    If TypeOf e Is Shape Then m_map.FlashShape(CType(e, Shape))
                Next
            End If
            Me.Update()
            My.Application.DoEvents()
        End If
    End Sub

    Private Sub m_job_Completed(ByVal fname As String, ByVal loc As LatLong, ByVal thumbnail As System.Windows.Media.Imaging.BitmapImage) Handles m_job.Completed
        UpdateProgress("loaded image " & m_job.Name, True)
    End Sub

    Private Sub m_job_ExceptionOccurred(ByVal ex As System.Exception) Handles m_job.ExceptionOccurred
        UpdateProgress("exception: " & ex.Message, True)
    End Sub

    Private Delegate Sub DlgUpdateProgress(ByVal msg As String, ByVal doevents As Boolean)
    Private Sub UpdateProgress(Optional ByVal msg As String = "", Optional ByVal doevents As Boolean = False)
        If USE_INVOKE And InvokeRequired Then
            BeginInvoke(New DlgUpdateProgress(AddressOf UpdateProgress), msg, doevents)
        Else
            If msg <> "" Then
                If txtStatus.Text = "" Then
                    txtStatus.Text = msg
                Else
                    txtStatus.AppendText(vbCrLf & msg)
                End If
            End If
            barJob.PerformStep()
            If doevents Then
                Me.Update()
                My.Application.DoEvents()
            End If
        End If
    End Sub

    Private Sub btnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClose.Click
        Me.Close()
    End Sub

    Private Sub SetMapExtent() Handles rdoWorld.CheckedChanged, rdoCONUS.CheckedChanged, rdoNorthAmerica.CheckedChanged
        If rdoWorld.Checked Then m_map.SetMapExtent(eWorld)
        If rdoCONUS.Checked Then m_map.SetMapExtent(eCONUS)
        If rdoNorthAmerica.Checked Then m_map.SetMapExtent(eNorthAmerica)
    End Sub

    Private Sub chkTimeZones_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkTimeZones.CheckedChanged
        m_map.ClearLayer("TimeZone")
        m_map.LoadTimeZones(chkTimeZones.Checked, False)
    End Sub

    Private Sub CatalogQueueStatusForm_Move(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Move
        MoveSqlForm()
    End Sub

    Private Sub CatalogQueueStatusForm_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
        MoveSqlForm()
    End Sub

    Private Sub ImageLoaderForm_VisibleChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.VisibleChanged
        If Not Visible Then Return
        MoveSqlForm()
        g_sqlinspector.Show()
    End Sub

    Private Sub btnLoadImage_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLoadImage.Click
        If My.Computer.Keyboard.ShiftKeyDown Then
            LoadChinaBugPhoto()
            Return
        End If
        g_imageloader.AddImage(IO.Path.Combine(IO.Directory.GetCurrentDirectory(), My.Settings.RTS_TestPhoto3), g_connection)
        'g_loaderform.Show()
    End Sub

    Private Sub LoadChinaBugPhoto()
        g_loaderform.BugMode()
        'g_loaderform.Show()
        g_imageloader.AddImage(IO.Path.Combine(IO.Directory.GetCurrentDirectory(), My.Settings.RTS_TestPhoto4), g_connection)
    End Sub

    Private Sub BugMode()
        m_map.LoadMap(True)
        m_map.LoadTimeZones(True, True)
    End Sub


End Class